package io.seata.sample.service;

import io.seata.sample.feign.OrderFeignClient;
import io.seata.sample.feign.StorageFeignClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @author jimin.jm@alibaba-inc.com
 * @date 2019/06/14
 */
@Service
public class BusinessService {

    @Autowired
    private StorageFeignClient storageFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 减库存，下订单
     *
     * @param userId
     * @param commodityCode
     * @param orderCount
     */
    @GlobalTransactional(timeoutMills = 300000, name = "")
    public void purchase(String userId, String commodityCode, int orderCount) {
        System.out.println("开始扣库存, 扣"+orderCount);
        storageFeignClient.deduct(commodityCode, orderCount);
        System.out.println("开始创建订单");
        orderFeignClient.create(userId, commodityCode, orderCount);
        System.out.println("检查库存和账户是否正常, 不正常就回滚");
        if (!validData()) {
            throw new RuntimeException("账户或库存不足,执行回滚");
        }
    }

    @PostConstruct
    @Transactional
    public void initData() {
        jdbcTemplate.update("delete from seata_account.account_tbl");
        jdbcTemplate.update("delete from seata_order.order_tbl");
        jdbcTemplate.update("delete from seata_storage.storage_tbl");
        jdbcTemplate.update("insert into seata_account.account_tbl(user_id,money) values('U100000','10000') ");
        jdbcTemplate.update("insert into seata_storage.storage_tbl(commodity_code,count) values('C100000','200') ");
    }

    public boolean validData() {
        Map accountMap = jdbcTemplate.queryForMap("select * from seata_account.account_tbl where user_id='U100000'");
        if (Integer.parseInt(accountMap.get("money").toString()) < 0) {
            return false;
        }
        Map storageMap = jdbcTemplate.queryForMap("select * from seata_storage.storage_tbl where commodity_code='C100000'");
        if (Integer.parseInt(storageMap.get("count").toString()) < 0) {
            return false;
        }
        return true;
    }
}
